Class Paster extends Gui {
    Input(x*) {
        GuiControlGet, text,, % this.Edit
        this.LV.Delete()
        if (SubStr(text, 1, 1) = Prefix) {
            this.LV.Add("Icon0", "Reload", "COMMAND")
            this.LV.Add("Icon0", "Exit", "COMMAND")
            this.SizeCtrl()
            return
        }
        for Index, Info in Fuzzy(text, this.List, "Search") ; search over this.list with the needle text, in the attribute Title
            this.LV.Add("Icon" this.Icons[Info.Exe], Info.Title, Info.hwnd)
        this.SizeCtrl()
    }

    ListViewAction(x*) {
        if (x.2 = "DoubleClick")
            this.Go()
    }

    Go() {
        Selected := this.LV.GetNext()
        ID := this.LV.GetText(Selected, 2)
        if (ID = "COMMAND") {
            text := this.LV.GetText(Selected, 1)
            Command(text)
            this.Close()
            return
        }
        ;this.Close()
        WinActivate % "ahk_id" ID
    }

    Stop() {
        Selected := this.LV.GetNext()
        ID := this.LV.GetText(Selected, 2)
        this.LV.Delete(Selected)
        this.SizeCtrl(Selected)
        for Index, Thing in this.List {
            if (Thing.hwnd = ID) {
                this.List.Remove(Index)
                break
            }
        }
        WinClose % "ahk_id" id
    }

    Move(Dir) {
        Selected := this.LV.GetNext()
        Count := this.LV.GetCount()
        New := Selected + Dir
        if (New < 1) || (New > Count)
            return
        this.LV.Modify(New, "Select Vis")
        this.Control("Focus", this.Edit)
    }

    Open() {
        if this.IsVisible
            return
        this.List := []
        this.LV.Delete()
        WinGet windows, List
        Added := []
        Loop %windows%
        {
            ID := windows%A_Index%
            if !WinExist("ahk_id" ID) || (this.ahkid = "ahk_id" id)
                continue
            WinGetTitle Title, % "ahk_id" ID
            WinGet, ProcessName, ProcessName, % "ahk_id" ID
            ProcessName := StrSplit(ProcessName, ".").1
            WinGet, Exe, ProcessPath, % "ahk_id" ID
            if StrLen(Exe) && StrLen(Title) && !(Title ~= IgnoreEquals) && (!Added.HasKey(Title)) {
                if !this.Icons.HasKey(Exe)
                    Icon := this.Icons[Exe] := this.IL.Add(Exe)
                else
                    Icon := this.Icons[Exe]
                if !Icon
                    continue
                this.List.Push({Title:Title, Exe:Exe, hwnd:ID, Search:(Title " " ProcessName)})
                if !AllowDupe
                    Added[Title] := true
                this.LV.Add("Icon" Icon, Title, ID)
            }
        }
        this.SizeCtrl()
        this.Show("Hide") ; "activate"
        this.Animate("FADE_IN", FadeTime)
        this.Show()
        this.Control("Focus", this.Edit)
    }

    SizeCtrl(Pos := 1) {
        static VERT_SCROLL, ROW_HEIGHT
        if !VERT_SCROLL
            SysGet, VERT_SCROLL, 2
        if !ROW_HEIGHT
            ROW_HEIGHT := LV_EX_GetRowHeight(this.LV.hwnd)
        this.LV.Redraw(false)
        Count := this.LV.GetCount()
        this.LV.ModifyCol(1, Width - ((Count > MaxItems) ? VERT_SCROLL : 0))
        this.Pos(A_ScreenWidth/2 - Width/2, A_ScreenHeight/2 - MoveUp,, 26 + (MaxItems > Count ? Count : MaxItems) * ROW_HEIGHT)
        this.Control("Move", this.LV.hwnd, "h" (ROW_HEIGHT * (MaxItems > Count ? Count : MaxItems)))
        this.LV.Modify((Pos>Count?Count:Pos), "Select Vis")
        this.LV.ModifyCol(2, 0)
        this.LV.Redraw(true)
    }

    Close() {
        if !this.IsVisible
            return
        this.SetText(this.Edit, "")
        this.Hide()
    }

    Toggle() {
        this[this.IsVisible ? "Close" : "Open"]()
    }

    CtrlBackspace() {
        this.Control("-Redraw", "Edit1")
        ControlSend, Edit1, ^+{Left}{Backspace}, % this.ahkid
        this.Control("+Redraw", "Edit1")
    }

    Escape() {
        this.Close()
    }
}

#Include lib\Class_GUI.ahk
